package com.beesphere.products.throttling.processor;

import com.beesphere.products.throttling.UnitOfWork;
import com.beesphere.products.throttling.timing.TimeExpression;

public class Delayer extends DelayProcessorSupport {
    private TimeExpression timeExpression;
    private long delay;

    public Delayer (Processor processor, 
    		TimeExpression timeExpression, long delay) {
        super (processor);
        this.timeExpression = timeExpression;
        this.delay = delay;
    }

    @Override
    public String toString() {
        return "Delayer[on: " + timeExpression + " delay: " + delay + " to: " + getProcessor() + "]";
    }

    // Properties
    // -------------------------------------------------------------------------
    public long getDelay() {
        return delay;
    }

    /**
     * Sets the delay from the publish time; which is typically the time from
     * the expression or the current system time if none is available
     */
    public void setDelay(long delay) {
        this.delay = delay;
    }

    // Implementation methods
    // -------------------------------------------------------------------------

    /**
     * Waits for an optional time period before continuing to process the
     * exchange
     */
    protected void delay (UnitOfWork unitOfWork) throws Exception {
        long time = 0;
        if (timeExpression != null) {
            time = timeExpression.evaluate (unitOfWork);
        }
        if (time <= 0) {
            time = defaultProcessTime (unitOfWork);
        }

        time += delay;

        waitUntil (time, unitOfWork);
    }

    /**
     * A Strategy Method to allow derived implementations to decide the current
     * system time or some other default exchange property
     * 
     * @param exchange
     */
    protected long defaultProcessTime (UnitOfWork throttledPiece) {
        return currentSystemTime();
    }

	@Override
	protected boolean isRunAllowed() {
		return true;
	}

}
